#include "SFMLTileEngine.h"
#include "SFML2DRenderEngine.h"
#include "..\Managers\RenderManager.h"
#include <fstream>
#include "..\rapidxml.hpp"
#include "..\Debug\DebugLog.h"
#include "..\Managers\SFMLTextureManager.h"
#include "..\Managers\SFMLSpriteManager.h"

using namespace vn;

SFMLTileEngine::SFMLTileEngine(float p_layer) : SFMLDrawable(p_layer){}
SFMLTileEngine::~SFMLTileEngine(void){ m_tiles.clear(); }

void SFMLTileEngine::draw(sf::RenderWindow& p_renderWindow)
{
	for (auto it = m_tiles.begin(); it != m_tiles.end(); it++)
		p_renderWindow.draw((*it));
}

void SFMLTileEngine::draw(sf::RenderTexture& p_renderTexture)
{
	for (auto it = m_tiles.begin(); it != m_tiles.end(); it++)
		p_renderTexture.draw((*it));
}

void SFMLTileEngine::loadTiles(const std::string& p_filepath)
{
	std::string xmlContent;
	std::ifstream file(p_filepath);
	if (file)
	{
		std::string line;
		while (std::getline(file, line))
			xmlContent += line;
		file.close();
	}
	else
	{
		Debug::log("ERROR: Can't open xml document " + p_filepath);
		abort();
	}
	std::vector<char> xmlBuffer = std::vector<char>(xmlContent.begin(), xmlContent.end());
	xmlBuffer.push_back('\0');
	rapidxml::xml_document<> doc;
	doc.parse<rapidxml::parse_no_data_nodes>(&xmlBuffer[0]);
	rapidxml::xml_node<>* root = doc.first_node();
	std::string id = root->first_attribute("filename")->value();
	std::string filename = "tilesets\\" + id;
	m_tileSize = static_cast<unsigned int>(atoi(root->first_attribute("tilesize")->value()));

	m_position.x = static_cast<float>(atof(root->first_attribute("x")->value()));
	m_position.y = static_cast<float>(atof(root->first_attribute("y")->value()));
	m_dimension.w = static_cast<float>(atof(root->first_attribute("w")->value()));
	m_dimension.h = static_cast<float>(atof(root->first_attribute("h")->value()));
	m_dimension.x = m_position.x;
	m_dimension.y = m_position.y;
	

	rapidxml::xml_node<>* tile = root->first_node("tile");
	SFMLTextureManager* textureManager = &static_cast<SFML2DRenderEngine*>(RenderManager::getSingleton().getRenderEngine())->getSpriteManager().getTextureManager();

	while (tile)
	{
		int tileX = atoi(tile->first_attribute("x")->value());
		int tileY = atoi(tile->first_attribute("y")->value());
		float posX = static_cast<float>(atof(tile->first_attribute("posX")->value()));
		float posY = static_cast<float>(atof(tile->first_attribute("posY")->value()));
		sf::Sprite sprite;
		sprite.setScale(SCALEF, SCALEF);
		sprite.setTexture(textureManager->loadTexture(id, filename, true, false));
		sprite.setTextureRect(sf::IntRect(tileX * static_cast<int>(m_tileSize), tileY * static_cast<int>(m_tileSize), static_cast<int>(m_tileSize), static_cast<int>(m_tileSize)));
		sprite.setPosition((m_position.x + (posX * static_cast<float>(m_tileSize))) * SCALEF, (m_position.y + (posY * static_cast<float>(m_tileSize))) * SCALEF);
		m_tiles.push_back(sprite);
		tile = tile->next_sibling("tile");
	}

}

void SFMLTileEngine::setPosition(const vn::Vector2& p_position)
{
	for (auto it = m_tiles.begin(); it != m_tiles.end(); it++)
	{
		(*it).setPosition((*it).getPosition().x + (p_position.x * SCALEF), (*it).getPosition().y + (p_position.y * SCALEF));
	}
	m_position = p_position;
}

void SFMLTileEngine::setDoRender(bool p_value)
{
	m_render = p_value;
}